﻿using System;
using IQIGame.Onigao.Framework.Serialization;
using IQIGame.Onigao.GamePlay;
using LFloatMath.Math;

namespace IQIGame.Onigao.Logic
{
    public class SkillEffective_CustomPropertyInt : SkillEffective
    {
        protected override ISerializeCustomPOD OnExecute(SkillEffectiveData data, Unit target, SkillEffectiveContext context, int effectiveIndex, out SkillEffectiveResponse startResp)
        {
            startResp = null;
            if (data.effectiveConfig.customConfig is SkillEffective_CustomProperty_ConfigData rConfig)
            {
                var nValue = BattleUtil.GetValue(rConfig.value, context.skill.executer, target);
                this.SetProperty(target, (ECustomProperty)rConfig.propertyKey, rConfig.customKey, (ECustomPropertyChangeType)rConfig.type, nValue);
            }
            return null;
        }

        protected override ISerializeCustomPOD OnActionExecute(SkillEffectiveData data, SkillActionNode action, Unit target, ref SkillEffectiveContext context, int effectiveIndex)
        {
            if (action.customConfig is SkillEffectiveAction_CustomProperty_ConfigData rConfig)
            {
                var nValue = rConfig.value.GetValue(context.skill.executer, target, context).ToInt();
                this.SetProperty(target, (ECustomProperty)rConfig.propertyKey, rConfig.customKey, (ECustomPropertyChangeType)rConfig.type, nValue);
            }

            return null;
        }

        private void SetProperty(Unit rTarget, ECustomProperty property, string customKey, ECustomPropertyChangeType changeType, int value)
        {
            var rComp = rTarget.GetComponent<CustomPropertyComponent>(ETComponentType.CustomPropertyComponent);
            if (rComp == null)
            {
                return;
            }
            var nTargetValue = 0;
            switch (changeType)
            {
                case ECustomPropertyChangeType.Add:
                {
                    var nProperty = string.IsNullOrEmpty(customKey) ? rComp.GetProperty<int>(property) : rComp.GetProperty(customKey);
                    nTargetValue = nProperty + value;
                    break;
                }
                case ECustomPropertyChangeType.Remove:
                {
                    var nProperty = string.IsNullOrEmpty(customKey) ? rComp.GetProperty<int>(property) : rComp.GetProperty(customKey);
                    nTargetValue = nProperty - value;
                    break;
                }
                case ECustomPropertyChangeType.Set:
                {
                    nTargetValue = value;
                    break;
                }
                case ECustomPropertyChangeType.Reset:
                    break;
            }
            nTargetValue = Math.Max(nTargetValue, 0);
            if (string.IsNullOrEmpty(customKey))
            {
                rComp.SetProperty(property, nTargetValue, ETAnyType.Int32);
            }
            else
            {
                rComp.SetProperty(customKey, nTargetValue);
            }
        }

#if UNITY_EDITOR
        public override string ToString(SkillCustomConfig config)
        {
            ECustomProperty property = default;
            string customKey = string.Empty;
            switch (config)
            {
                case SkillEffective_CustomProperty_ConfigData rData:
                    property = (ECustomProperty)rData.propertyKey;
                    customKey = rData.customKey;
                    break;
                case SkillEffectiveAction_CustomProperty_ConfigData rData:
                    property = (ECustomProperty)rData.propertyKey;
                    customKey = rData.customKey;
                    break;
            }
            return $"添加custom计数[{property}/{customKey}]";
        }
#endif

        public enum ECustomPropertyChangeType
        {
            Add,
            Remove,
            Set,
            Reset
        }
    }
}